package com.itheima.health.service.impl;

import com.itheima.health.dao.*;
import com.itheima.health.pojo.Order;
import com.itheima.health.pojo.Setmeal;
import com.itheima.health.service.ReportService;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;

import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Override
    public Object getMemberReport() {
        List<String> months = new ArrayList<>();
        List<Integer> memberCount = new ArrayList<>();
        LocalDate end = LocalDate.now();
        for (int i = 0; i <= 12; i++) {
            LocalDate date = end.minusMonths(i);
            // 获取当前月的第一天
            LocalDate beginTime = date.with(TemporalAdjusters.firstDayOfMonth());
            // 获取当前月的最后一天
            LocalDate endTime = date.with(TemporalAdjusters.lastDayOfMonth());
            // 定义需要的日期格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
            // 将日期格式化为所需的格式
            String yearMonth = date.format(formatter);
            months.add(yearMonth);
            Map map = new HashMap();
            map.put("beginTime",beginTime);
            map.put("endTime",endTime);
            Integer integer = memberMapper.selectByMap(map);
            memberCount.add(integer);
        }
        Collections.reverse(months);
        Collections.reverse(memberCount);
        Map map = new HashMap();
        map.put("months",months);
        map.put("memberCount",memberCount);

        return map ;
    }
    /**
     * 展示套餐分布情况
     * @return
     */
    public Object getSetmealReport() {
        List<String> stringList = new ArrayList<>();
        Map map = new HashMap();

        List<Map<String,Object>> mapList = new ArrayList<>();
        List<Setmeal> setmealList= setmealMapper.selectAll();
        for (Setmeal setmeal : setmealList) {
            stringList.add(setmeal.getName());
            Integer integer= orderMapper.selectCountId(setmeal.getId());
            Map map1 = new HashMap();
            map1.put("name",setmeal.getName());
            map1.put("value",integer);
            mapList.add(map1);
        }
        map.put("setmealNames",setmealList);
        map.put("setmealCount",mapList);
        return map;
    }

    /**
     * 运营数据统计
     * @return
     */
    public Map getBusinessReportData() {
        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = now.format(formatter);
        //今日到诊数量
        String orderstatusYes = Order.ORDERSTATUS_YES;
        Integer integer = orderMapper.selectByDateAndStatus(now,orderstatusYes);


        // 今日新增会员数
        LocalDate days = now;
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format1 = days.format(formatter1);
        Map map3 = new HashMap();
        map3.put("beginTime",format1);
        Integer integer3 = memberMapper.selectByMap(map3);


        //本周到诊数
        Calendar c1 = Calendar.getInstance();
        int dayOfWeek1 = c1.get(Calendar.DAY_OF_WEEK); // 获取今天是周几
        int offset1 = 2 - dayOfWeek1; // 计算距离周一还有多少天，如果今天是周一则offset=0
        c1.add(Calendar.DATE, offset1); // 获取本周周一的日期
        Date beginTime2 = c1.getTime();
        c1.add(Calendar.DATE, 6); // 获取本周周日的日期
        Date endTime2 = c1.getTime();
        Integer integer4 = orderMapper.selectByWeekDateAndStatus(beginTime2,endTime2,orderstatusYes);


        //本月新增会员数
        // 获取当前月的第一天
        LocalDate beginTime = now.with(TemporalAdjusters.firstDayOfMonth());
        // 获取当前月的最后一天
        LocalDate endTime = now.with(TemporalAdjusters.lastDayOfMonth());
        Map map1 = new HashMap();
        map1.put("beginTime",beginTime);
        map1.put("endTime",endTime);
        Integer integer1 = memberMapper.selectByMap(map1);


        //本周新增会员数
        Calendar c = Calendar.getInstance();
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); // 获取今天是周几
        int offset = 1 - dayOfWeek; // 计算距离周一还有多少天，如果今天是周一则offset=0
        c.add(Calendar.DATE, offset); // 获取本周周一的日期
        Date beginTime1 = c.getTime();
        c.add(Calendar.DATE, 6); // 获取本周周日的日期
        Date endTime1 = c.getTime();
        Map map2 = new HashMap();
        map2.put("beginTime",beginTime1);
        map2.put("endTime",endTime1);
        Integer integer2 = memberMapper.selectByMap(map2);


        //总会员数
        Integer integer5 = memberMapper.selectAll();

        //本月预约数
        // 获取当前时间
        Calendar calendar = Calendar.getInstance();
        // 置为本月的第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        // 获取本月第一天的日期
        Date firstDayOfMonth = calendar.getTime();
        // 将时间置为下个月的第一天
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        // 将时间减去1天，即为本月最后一天
        calendar.add(Calendar.DATE, -1);
        // 获取本月最后一天的日期
        Date lastDayOfMonth = calendar.getTime();
        Integer integer6 = orderMapper.selectByWeekDateAndStatus(firstDayOfMonth, lastDayOfMonth, null);

        //本月到诊数
        Integer integer7 = orderMapper.selectByWeekDateAndStatus(firstDayOfMonth, lastDayOfMonth, Order.ORDERSTATUS_YES);


        //今日预约数
        LocalDate localDate = LocalDate.now();
        Integer integer8 = orderMapper.selectByDateAndStatus(localDate, null);

        //本周预约数
        Integer integer9 = orderMapper.selectByWeekDateAndStatus(beginTime1, endTime1, null);


        // 热门套餐
        List<Map<String,Object>> mapList = new ArrayList<>();

        List<Setmeal> setmealList= setmealMapper.selectAll();
        Integer seletecuntid = orderMapper.selectCountId(null);
        for (Setmeal setmeal : setmealList) {
            Integer integer10= orderMapper.selectCountId(setmeal.getId());
            Map map = new HashMap();
            map.put("name",setmeal.getName());
            map.put("setmeal_count",integer10);
            Double aDouble = (double)integer10 / seletecuntid;
            map.put("proportion",aDouble);
            mapList.add(map);
        }

        Map map = new HashMap();
        map.put("todayVisitsNumber",integer); //今日到诊数量
        map.put("reportDate",format); // 今天的日期
        map.put("todayNewMember",integer3); // 新增会员数
        map.put("thisWeekVisitsNumber",integer4);//本周到诊数
        map.put("thisMonthNewMember",integer1);//本月新增会员数
        map.put("thisWeekNewMember",integer2);//本周新增会员数
        map.put("totalMember",integer5);//总会员数
        map.put("thisMonthOrderNumber",integer6);//本月预约数
        map.put("thisMonthVisitsNumber",integer7);//本月到诊数
        map.put("todayOrderNumber",integer8);//今日预约数
        map.put("thisWeekOrderNumber",integer9);//本周预约数
        map.put("hotSetmeal",mapList);


        return map;
    }

    /**
     * 导出Excel报表
     * @param response
     */
    public void exportBusinessReport(HttpServletResponse response) {
        Map map = getBusinessReportData();
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/report_template.xlsx");
        try {
            //基于提供好的模板文件创建一个新的Excel表格对象
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            //获得Excel文件中的一个Sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");
            //获得第3行
            XSSFRow row = sheet.getRow(2);
            row.getCell(5).setCellValue((String) map.get("reportDate"));
            //获得第5行
            row = sheet.getRow(4);
            row.getCell(5).setCellValue((Integer) map.get("todayNewMember"));// 新增会员数
            row.getCell(7).setCellValue((Integer) map.get("totalMember"));//总会员数
            //获得第6行
            row = sheet.getRow(5);
            row.getCell(5).setCellValue((Integer) map.get("thisWeekOrderNumber"));//本周新增会员数
            row.getCell(7).setCellValue((Integer) map.get("thisWeekVisitsNumber"));//本月新增会员数
            //获得第8行
            row = sheet.getRow(7);
            row.getCell(5).setCellValue((Integer) map.get("todayOrderNumber"));//今日预约数
            row.getCell(7).setCellValue((Integer) map.get("todayVisitsNumber"));//今日到诊数量
            //获得第9行
            row = sheet.getRow(8);
            row.getCell(5).setCellValue((Integer) map.get("thisWeekOrderNumber"));//本周预约数
            row.getCell(7).setCellValue((Integer) map.get("thisWeekVisitsNumber"));//本周到诊数
            //获得第12行
            row = sheet.getRow(9);
            row.getCell(5).setCellValue((Integer) map.get("thisMonthOrderNumber"));//本月预约数
            row.getCell(7).setCellValue((Integer) map.get("thisMonthVisitsNumber"));//本月到诊数
            List<Map<String,Object>> mapList= (List<Map<String, Object>>) map.get("hotSetmeal");
            int size = mapList.size();
            for (int i = 0; i < mapList.size(); i++) {
                for (Map<String, Object> objectMap : mapList) {
                    row = sheet.getRow(12+i);
                    row.getCell(4).setCellValue((String) objectMap.get("name"));
                    row.getCell(5).setCellValue((Integer) objectMap.get("setmeal_count"));
                    row.getCell(6).setCellValue((Double) objectMap.get("proportion"));
                }
            }
            //通过输出流将文件下载到客户端浏览器中
            ServletOutputStream out = response.getOutputStream();

            response.setHeader("Content-Disposition","attachment;fileName=itcast.xlsx");

            excel.write(out);
            //关闭资源
            out.flush();
            out.close();
            excel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
